<?php
/**
 * PhpStorm
 * User: zucheng
 * Date: 2019/3/25
 */

namespace App\Http\Controllers\Api\V1;

use App\Library\Common;
use App\Library\Time;
use App\Models\CarSite;
use App\Models\DriverRoutes;
use App\Models\Member;
use App\Models\MemberRelation;
use App\Models\Order;
use App\Models\OwnerRoutes;
use App\Models\Shipping;
use App\Services\CarService;
use App\Services\OrderService;
use App\Services\RouteService;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Validator;
use App\Http\Controllers\Api\ApiController;
use Illuminate\Http\Request;

class OrderController extends ApiController
{
    /**
     * 发布货源
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function createOrder(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'user_type' => 'required',
                'sender_uuid' => 'required|size:36',
                'receiver_uuid' => 'required|size:36',
                'src_address' => 'required',
                'src_location' => 'required',
                'dst_address' => 'required',
                'dst_location' => 'required',
                'cargo_type' => 'required|max:32',
                'price' => 'required',
                'price_unit' => 'required|integer',
                'price_desc' => 'max:100',
                'loss_deduct' => 'required',
                'loss_limit' => 'required_if:loss_deduct,1',
                'loss_price' => 'required_if:loss_deduct,1',
                'loss_price_unit' => 'required_if:loss_deduct,1',
                'car_scheme_id' => 'required|integer',
                'total_car_num' => 'required|integer',
                'order_remark' => 'max:512',
                'start_time' => 'required|date',
                'end_time' => 'required|date',
                'pay_option_type ' => 'required|number',// 付款方式1卸货付款 2回单付款
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $createUuid = $request->get('user_uuid');
            if ($request->get('user_type') == Member::ROLE_OWNER) {
                $ownerUuid = $createUuid;
            } else {
                $userId = Member::query()->where('uuid', $createUuid)->value('id');
                $relation = MemberRelation::query()
                    ->where('member_id', $userId)
                    ->first();
                if (empty($relation)) {
                    throw new \Exception('找不到发单人对应的货主信息');
                }
                $ownerUuid = Member::query()
                    ->where('id', $relation->parent_id)
                    ->value('uuid');
            }

            // 获取路由信息
            $routeId = RouteService::getInstance()->addOwnerRoute($ownerUuid, $request->get('src_location'), $request->get('dst_location'), $request->get('src_address'), $request->get('dst_address'));
            $sender_uuid = $request->get('sender_uuid');
            $receiver_uuid = $request->get('receiver_uuid');
            $data = [
                'order_no' => Common::createOrderNo(),
                'owner_uuid' => $ownerUuid,
                'sender_uuid' => empty($sender_uuid) == true ? $ownerUuid : $sender_uuid,
                'receiver_uuid' => $receiver_uuid,
                'create_uuid' => $createUuid,
                'route_id' => $routeId,
                'cargo_type' => $request->get('cargo_type'),
                'price' => $request->get('price') * 100,
                'price_unit' => $request->get('price_unit'),
                'price_desc' => $request->get('price_desc', ''),
                'loss_deduct' => $request->get('loss_deduct'),
                'loss_limit' => $request->get('loss_limit', 0),
                'loss_price' => $request->get('loss_price', 0) * 100,
                'loss_price_unit' => $request->get('loss_price_unit', 0),
                'car_scheme_id' => $request->get('car_scheme_id'),
                'total_car_num' => $request->get('total_car_num'),
                'order_remark' => $request->get('order_remark', ''),
                'start_time' => date('Y-m-d H:i:s', strtotime($request->get('start_time'))),
                'end_time' => date('Y-m-d H:i:s', strtotime($request->get('end_time'))),
                'pay_option_type' => $request->get('pay_option_type'),
            ];
            $order = Order::create($data);

            return $this->success('success', ['order_no' => $order->order_no]);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 常用发货人列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUsedSender(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'user_type' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $query = Order::query();
            if ($request->get('user_type') == Member::ROLE_OWNER) {
                $query = $query->where('owner_uuid', $request->get('user_uuid'));
            } else {
                $query = $query->where('create_uuid', $request->get('user_uuid'));
            }
            $senders = $query->pluck('sender_uuid')->toArray();
            if (empty($senders)) {
                return $this->success();
            }
            $members = Member::query()
                ->whereIn('uuid', $senders)
                ->select([
                    'name',
                    'phone as mobile',
                    'uuid as user_uuid',
                ])
                ->get()
                ->toArray();
            foreach ($members as &$member) {
                is_null($member['name']) && $member['name'] = '';
            }

            return $this->success('success', $members);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 常用收货人列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUsedReceiver(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'user_type' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $query = Order::query();
            if ($request->get('user_type') == Member::ROLE_OWNER) {
                $query = $query->where('owner_uuid', $request->get('user_uuid'));
            } else {
                $query = $query->where('create_uuid', $request->get('user_uuid'));
            }
            $receivers = $query->pluck('receiver_uuid')->toArray();
            if (empty($receivers)) {
                return $this->success();
            }
            $members = Member::query()
                ->whereIn('uuid', $receivers)
                ->select([
                    'name',
                    'phone as mobile',
                    'uuid as user_uuid',
                ])
                ->get()
                ->toArray();
            foreach ($members as &$member) {
                is_null($member['name']) && $member['name'] = '';
            }

            return $this->success('success', $members);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取货源对应的司机信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getOrderDriverList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $order = Order::select(['id'])
                ->where('order_no', $request->get('order_no'))
                ->firstOrFail();

            // 获取司机信息
            $shipper = Shipping::where('order_id', $order->id)
                ->pluck('driver_uuid')
                ->toArray();
            if (empty($shipper)) {
                return $this->success('success');
            }

            $users = Member::with([
                'driver' => function ($query) {
                    $query->select(['member_id', 'car_no']);
                }
            ])->whereIn('uuid', $shipper)
                ->where('role_id', Member::ROLE_DRIVER)
                ->get()
                ->toArray();
            if (empty($users)) {
                return $this->success('success');
            }

            $data = [];
            foreach ($users as $key => $user) {
                $data[$key]['user_uuid'] = $user['uuid'];
                $data[$key]['name'] = $user['name'];
                $data[$key]['mobile'] = $user['phone'];
                $data[$key]['car_no'] = $user['driver']['car_no'];
            }

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取当前用户下的货源列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function ownerOrderList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'user_type' => 'required',
                'query_status' => 'required|integer',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $status = $request->get('query_status');
            $userUuid = $request->get('user_uuid');
            $userType = $request->get('user_type');
            $userType = str_replace('，', ',', $userType);

            $fields = [
                'id',
                'order_no',
                'status',
                'cargo_type',
                'price',
                'route_id',
                'price_unit',
                'total_car_num',
                'shipping_car_num',
                'created_at as publish_time',
                'start_time',
                'end_time',
                'finish_time',
                'cancel_time',
            ];
            $order = Order::with([
                    'shipping' => function ($query) {
                        $query->select(['id', 'order_id', 'shipping_no', 'status']);
                    }, 'route']
            )->select($fields)
                ->where('status', $request->get('query_status'))
                ->orderBy('id', 'desc');

            //根据不同角色查询
            $order = $order->where(function ($order) use ($userType, $userUuid) {
                $arrUserType = explode(',', $userType);

                $order->where('v_orders.owner_uuid', $userUuid); //货主

                //发单人
                if (in_array(Member::ROLE_ORDER, $arrUserType)) {
                    $order->orWhere('v_orders.create_uuid', $userUuid);
                }
                //发货人
                $order->orWhere('v_orders.sender_uuid', $userUuid);

                //收货人
                $order->orWhere('v_orders.receiver_uuid', $userUuid);
            });

            $order = $order->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))->toArray();
            if ($order['total'] == 0) {
                return $this->table();
            }

            $data = [];
            foreach ($order['data'] as $key => $item) {
                /**
                 * | $shipmentNum | 已装货车辆数 |
                 * | $transitNum | 运输中车辆数 |
                 * | $waitPayNum | 等待支付车辆数 |
                 * | $doneNum | 已完结车辆数量 |
                 */
                $shipmentNum = $transitNum = $waitPayNum = $doneNum = 0;
                foreach ($item['shipping'] as $shipping) {
                    if ($shipping['status'] == Shipping::$statusLoadComplete) {
                        $shipmentNum++;
                        $transitNum++;
                    }
                    if ($shipping['status'] == Shipping::$statusUnLoadComplete) {
                        $waitPayNum++;
                    }
                    if ($shipping['status'] == Shipping::$statusTransportPayComplete) {
                        $doneNum++;
                    }
                }
                unset($item['shipping']);
                $tmp['shipment_num'] = $shipmentNum;
                $tmp['transit_num'] = $transitNum;
                $tmp['wait_pay_num'] = $waitPayNum;
                $tmp['done_num'] = $doneNum;

                $tmp['src_address'] = $item['route']['src_address'];
                $tmp['dst_address'] = $item['route']['dst_address'];

                unset($item['route']);

                $item['price'] = $item['price'] / 100; //单位转换

                $data[$key] = $item;
                $data[$key] = array_merge($data[$key], $tmp);
            }

            return $this->table($data, $order['total']);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 订单进度
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function orderSchedule(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $order = Order::with('shipping')
                ->where('order_no', $request->get('order_no'))
                ->first();
            if (empty($order)) {
                return $this->success('no data');
            }
            $order = $order->toArray();
            $ret = [
                'route_id' => $order['route_id'],
                'order_no' => $order['order_no'],
                'status' => $order['status'],
                'total_car_num' => $order['total_car_num'],
                'shipping_car_num' => $order['shipping_car_num'],
            ];

            /**
             * | $waitLoadNum | 等待装货车辆数 |
             * | $shipmentNum | 已装货车辆数 |
             * | $arriveNum | 已到达车辆数 |
             * | $totalLoadNum | 已装总量
             */
            $shipmentNum = $arriveNum = $totalLoadNum = $waitLoadNum = 0;
            foreach ($order['shipping'] as $shipping) {
                if ($shipping['global_status'] <= Shipping::GLOBAL_DRIVER_ARRIVE_SRC) {
                    $waitLoadNum++;
                }
                if ($shipping['status'] >= Shipping::$statusLoadComplete) {
                    $shipmentNum++;
                    $totalLoadNum += $shipping['load_num'];
                }
                if ($shipping['global_status'] >= Shipping::GLOBAL_DRIVER_ARRIVE_DST) {
                    $arriveNum++;
                }
            }
            $ret['wait_load_num'] = $waitLoadNum;
            $ret['shipment_num'] = $shipmentNum;
            $ret['arrive_num'] = $arriveNum;
            $ret['total_load_num'] = $totalLoadNum;

            $route = RouteService::getInstance()->getDetailedAddressByRouteId($order['route_id'], new OwnerRoutes());
            if (!empty($route)) {
                $ret['src_address'] = $route['srcDetail'];
                $ret['dst_address'] = $route['dstDetail'];
            }

            unset($order['shipping']);
            unset($order['route_id']);


            return $this->success('success', $ret);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 订单详情 - 货主端
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function ownerOrderInfo(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $order = Order::with(['scheme', 'sender', 'receiver'])
                ->where('order_no', $request->get('order_no'))
                ->first();
            if (empty($order)) {
                return $this->success('no data');
            }
            $order = $order->toArray();

            $route = RouteService::getInstance()->getDetailedAddressByRouteId($order['route_id'], new OwnerRoutes(), [4], [4]);
            if (!empty($route)) {
                $order['src_address'] = $route['srcDetail'];
                $order['dst_address'] = $route['dstDetail'];
                $order['distance'] = $route['distance'];
            }

            // 发货人和收货人信息
            $order['sender_name'] = $order['sender']['name'];
            $order['sender_phone'] = $order['sender']['phone'];
            $order['receiver_name'] = $order['receiver']['name'];
            $order['receiver_phone'] = $order['receiver']['phone'];;

            // 车辆类型
            $carSites = CarSite::select(['site_value', 'site_type'])
                ->where('site_status', 1)
                ->whereIn('id', [
                    $order['scheme']['model_site_id'],
                    $order['scheme']['box_site_id'],
                    $order['scheme']['length_site_id'],
                ])->pluck('site_value', 'site_type');
            $order['car_model'] = $carSites[CarService::CAR_MODEL] ?? '';
            $order['car_box'] = $carSites[CarService::CAR_BOX] ?? '';
            $order['car_length'] = $carSites[CarService::CAR_LENGTH] ?? '';

            unset($order['scheme']);
            unset($order['sender']);
            unset($order['receiver']);

            return $this->success('success', $order);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 待装货 货运记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function waitLoadCarList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $order = Order::select('id')->where('order_no', $request->get('order_no'))->firstOrFail();

            $shipping = Shipping::with(['driver', 'driver_extend'])
                ->where('order_id', $order->id)
                ->where('status', Shipping::$statusInfoPayComplete)
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if ($shipping['total'] == 0) {
                return $this->table();
            }

            $ret = [];
            foreach ($shipping['data'] as $item) {
                $ret[] = [
                    'shipping_no' => $item['shipping_no'],
                    'load_num' => $item['load_num'],
                    'load_pic' => $item['load_pic'],
                    'status' => $item['status'],
                    'global_status' => $item['global_status'],
                    'receive_time' => $item['created_at'],
                    'driver_name' => $item['driver']['name'] ?? '',
                    'driver_mobile' => $item['driver']['phone'] ?? '',
                    'car_no' => $item['driver_extend']['car_no'] ?? '',
                ];
            }

            return $this->table($ret, $shipping['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 运输中 货运记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function inTransitCarList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $order = Order::select('id')->where('order_no', $request->get('order_no'))->firstOrFail();

            $shipping = Shipping::with('driver', 'driver_extend')
                ->where('order_id', $order->id)
                ->where('status', Shipping::$statusLoadComplete)
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if ($shipping['total'] == 0) {
                return $this->table();
            }

            $ret = [];
            foreach ($shipping['data'] as $item) {
                $ret[] = [
                    'shipping_no' => $item['shipping_no'],
                    'load_num' => $item['load_num'],
                    'load_pic' => $item['load_pic'],
                    'status' => $item['status'],
                    'global_status' => $item['global_status'],
                    'shipment_end_time' => $item['shipment_end_time'] ?? '',
                    'shipment_remark' => $item['shipment_remark'] ?? '',
                    'unload_num' => $item['unload_num'] ?? '',
                    'unload_pic' => $item['unload_pic'] ?? '',
                    'deliver_end_time' => $item['deliver_end_time'] ?? '',
                    'driver_name' => $item['driver']['name'] ?? '',
                    'driver_mobile' => $item['driver']['phone'] ?? '',
                    'car_no' => $item['driver_extend']['car_no'] ?? '',
                ];
            }

            return $this->table($ret, $shipping['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 待结算 货运记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function waitPayCarList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $order = Order::select('id')->where('order_no', $request->get('order_no'))->firstOrFail();

            $shipping = Shipping::with('driver')
                ->where('order_id', $order->id)
                ->where('status', Shipping::$statusUnLoadComplete)
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if ($shipping['total'] == 0) {
                return $this->table();
            }

            $ret = [];
            foreach ($shipping['data'] as $item) {
                $ret[] = [
                    'shipping_no' => $item['shipping_no'],
                    'load_num' => $item['load_num'],
                    'load_pic' => $item['load_pic'],
                    'status' => $item['status'],
                    'global_status' => $item['global_status'],
                    'pay_status' => $item['pay_status'],
                    'unload_num' => $item['unload_num'] ?? '',
                    'unload_pic' => $item['unload_pic'] ?? '',
                    'deliver_end_time' => $item['deliver_end_time'] ?? '',
                    'deliver_remark' => $item['deliver_remark'] ?? '',
                    'shipment_end_time' => $item['shipment_end_time'],
                    'shipment_remark' => $item['shipment_remark'] ?? '',
                    'driver_name' => $item['driver']['name'] ?? '',
                    'driver_mobile' => $item['driver']['phone'] ?? '',
                    'car_no' => $item['driver_extend']['car_no'] ?? '',
                ];
            }

            return $this->table($ret, $shipping['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 已完成 货运记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function completeCarList(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $order = Order::select('id')->where('order_no', $request->get('order_no'))->firstOrFail();

            $shipping = Shipping::with('driver', 'driver_extend')
                ->where('order_id', $order->id)
                ->where('status', Shipping::$statusTransportPayComplete)
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if ($shipping['total'] == 0) {
                return $this->table();
            }

            $ret = [];
            foreach ($shipping['data'] as $item) {
                $ret[] = [
                    'shipping_no' => $item['shipping_no'],
                    'load_num' => $item['load_num'],
                    'load_pic' => $item['load_pic'],
                    'status' => $item['status'],
                    'global_status' => $item['global_status'],
                    'pay_status' => $item['pay_status'],
                    'unload_num' => $item['unload_num'] ?? '',
                    'unload_pic' => $item['unload_pic'] ?? '',
                    'deliver_end_time' => $item['deliver_end_time'] ?? '',
                    'deliver_remark' => $item['deliver_remark'] ?? '',
                    'shipment_end_time' => $item['shipment_end_time'],
                    'shipment_remark' => $item['shipment_remark'] ?? '',
                    'driver_name' => $item['driver']['name'] ?? '',
                    'driver_mobile' => $item['driver']['phone'] ?? '',
                    'car_no' => $item['driver_extend']['car_no'] ?? '',
                ];
            }

            return $this->table($ret, $shipping['total']);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 今日货源列表展示 - 展示给司机使用
     * @ses https://run.mockplus.cn/DQQd1cZtfuI7ebzw/index.html?to=4A4A5C29-F6AA-41B4-B382-101F9DF52836
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getTodayOrderListForDrivers(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'page' => 'required|integer',
                'limit' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $distance = $request->get('distance');
            $createdAt = $request->get('created_at', '1');
            $priceSortingTarget = $request->get('price_sorting_target') == 'desc' ? 'desc' : 'asc';
            $driverUuid = $request->get('driver_uuid', '');
            $srcCode = $request->get('src_code');
            $srcCodeType = $request->get('src_code_type');
            $dstCode = $request->get('dst_code');
            $dstCodeType = $request->get('dst_code_type');

            $preSql = OwnerRoutes::select(['id'])->where('status', 1);
            $preSql = OrderService::getInstance()->sectionQueryBuilder($preSql, $srcCode, $srcCodeType, $dstCode, $dstCodeType);

            $distance && $preSql->orderBy('driving_distance', 'desc');

            $filteredRoutes = $preSql->get()->toArray();

            if (!sizeof($filteredRoutes)) {
                return $this->success('暂无数据');
            }

            $finalRouteIds = array_column($filteredRoutes, 'id');

            // 货源列表展示
            $fields = [
                'v_orders.id',
                'v_orders.order_no',
                'v_orders.cargo_type',
                'v_orders.total_car_num',
                'v_orders.shipping_car_num',
                'v_orders.price',
                'v_orders.price_unit',
                'v_orders.route_id',
                'v_orders.start_time',
                'v_orders.end_time',
                'scheme.model_site_id',
                'scheme.box_site_id',
                'scheme.length_site_id',
                'v_owner_routes.driving_distance', // 驾车距离
                'v_owner_routes.line_distance', // 直线距离
            ];
            $res = Order::select($fields)
                ->leftJoin('v_car_schemes AS scheme', 'scheme.id', '=', 'v_orders.car_scheme_id')
                ->leftJoin('v_owner_routes', 'v_owner_routes.id', '=', 'v_orders.route_id')
                ->where('v_orders.status', Order::STATUS_PUBLISH)
                ->whereIn('v_orders.route_id', $finalRouteIds)
                ->where('v_orders.start_time', '>=', date('Y-m-d H:i:s'));

            if ($createdAt == 1) {
                $res = $res->orderBy('v_orders.created_at', 'desc');
            } else {
                $res = $res->orderBy('v_orders.created_at', 'asc');
            }
            $priceSortingTarget && $res = $res->orderBy('price', $priceSortingTarget);

            $res = $res->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if (empty($res['data'])) {
                return $this->success('暂无数据');
            }

            // 当前司机已接单标记
            $orderIds = array_column($res['data'], 'id');
            $shippingInfos = Shipping::query()
                ->select(['order_id'])
                ->where('driver_uuid', $driverUuid)
                ->whereIn('order_id', $orderIds)
                ->get()
                ->toArray();
            $shippingOrderIds = array_column($shippingInfos, 'order_id');

            $oRoute = new OwnerRoutes();
            foreach ($res['data'] as $key => $value) {

                // 价格转换为元
                $res['data'][$key]['price'] = $value['price'] / 100;

                $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($value['route_id'], $oRoute, [3], [3]);
                $res['data'][$key]['src'] = $routeInfo['srcDetail'];
                $res['data'][$key]['dst'] = $routeInfo['dstDetail'];
                $res['data'][$key]['car_need_num'] = intval($value['total_car_num']) - intval($value['shipping_car_num']);

                $carSites = CarSite::select(['site_value', 'site_type'])
                    ->where('site_status', 1)
                    ->whereIn('id', [
                        $value['model_site_id'],
                        $value['box_site_id'],
                        $value['length_site_id']
                    ])
                    ->get()
                    ->toArray();
                $siteInfo = sizeof($carSites) ? array_column($carSites, 'site_value', 'site_type') : [];
                $res['data'][$key]['car_model'] = $siteInfo[CarService::CAR_MODEL] ?? '';
                $res['data'][$key]['car_box'] = $siteInfo[CarService::CAR_BOX] ?? '';
                $res['data'][$key]['car_length'] = $siteInfo[CarService::CAR_LENGTH] ?? '';

                // 司机接单标记
                $res['data'][$key]['is_order_driver'] = in_array($value['id'], $shippingOrderIds) ? 1 : -1;

                // 时间转换
                $res['data'][$key]['start_time'] = date('Y-m-d', strtotime($value['start_time']));
                $res['data'][$key]['end_time'] = date('Y-m-d', strtotime($value['end_time']));

                unset(
                    $res['data'][$key]['id'],
                    $res['data'][$key]['model_site_id'],
                    $res['data'][$key]['box_site_id'],
                    $res['data'][$key]['length_site_id'],
                    $res['data'][$key]['route_id']
                );
            }

            return $this->table($res['data'], $res['total']);

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 订阅货源列表展示 - 展示给司机使用
     * @ses https://run.mockplus.cn/DQQd1cZtfuI7ebzw/index.html?to=4A4A5C29-F6AA-41B4-B382-101F9DF52836
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getSubscribedOrderListForDrivers(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'page' => 'required|integer',
                'limit' => 'required|integer',
                'driver_uuid' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $distance = $request->get('distance');
            $createdAt = $request->get('created_at', '1');
            $priceSortingTarget = $request->get('price_sorting_target') == 'desc' ? 'desc' : 'asc';
            $srcCode = $request->get('src_code');
            $srcCodeType = $request->get('src_code_type');
            $dstCode = $request->get('dst_code');
            $dstCodeType = $request->get('dst_code_type');

            $driverRoutes = DriverRoutes::select(['src_city_code', 'dst_city_code'])
                ->where('driver_uuid', $driverUuid)
                ->where('status', DriverRoutes::$statusOK)
                ->get()
                ->toArray();
            if (!sizeof($driverRoutes)) {
                return $this->success('您还没有订阅任何线路');
            }

            $preSql = OwnerRoutes::select(['id'])
                ->where(function ($query) use ($driverRoutes) {
                    foreach ($driverRoutes as $item) {
                        $query->orWhere(function ($query) use ($item) {
                            $query->where('src_city_code', $item['src_city_code'])
                                ->where('dst_city_code', $item['dst_city_code']);
                        });
                    }
                })->where('status', 1);
            $preSql = OrderService::getInstance()->sectionQueryBuilder($preSql, $srcCode, $srcCodeType, $dstCode, $dstCodeType);
            $distance && $preSql->orderBy('driving_distance', 'desc');

            $filteredRoutes = $preSql->get()->toArray();

            if (!sizeof($filteredRoutes)) {
                return $this->success('暂无数据');
            }

            $finalRouteIds = array_column($filteredRoutes, 'id');

            // 货源列表展示
            $fields = [
                'v_orders.id',
                'v_orders.order_no',
                'v_orders.cargo_type',
                'v_orders.total_car_num',
                'v_orders.shipping_car_num',
                'v_orders.price',
                'v_orders.price_unit',
                'v_orders.route_id',
                'v_orders.start_time',
                'v_orders.end_time',
                'scheme.model_site_id',
                'scheme.box_site_id',
                'scheme.length_site_id',
                'v_owner_routes.driving_distance', // 驾车距离
                'v_owner_routes.line_distance', // 直线距离
            ];
            $res = Order::select($fields)
                ->leftJoin('v_car_schemes AS scheme', 'scheme.id', '=', 'v_orders.car_scheme_id')
                ->leftJoin('v_owner_routes', 'v_owner_routes.id', '=', 'v_orders.route_id')
                ->where('v_orders.status', Order::STATUS_PUBLISH)
                ->where('v_orders.end_time', '>', date('Y-m-d H:i:s'))
                ->whereIn('v_orders.route_id', $finalRouteIds)
                ->where('v_orders.start_time', '>=', date('Y-m-d H:i:s'));

            if ($createdAt == 1) {
                $res = $res->orderBy('v_orders.created_at', 'desc');
            } else {
                $res = $res->orderBy('v_orders.created_at', 'asc');
            }
            $priceSortingTarget && $res = $res->orderBy('price', $priceSortingTarget);

            $res = $res->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if (empty($res['data'])) {
                return $this->success('暂无数据');
            }

            // 当前司机已接单标记
            $orderIds = array_column($res['data'], 'id');
            $shippingInfos = Shipping::query()
                ->select(['order_id'])
                ->where('driver_uuid', $driverUuid)
                ->whereIn('order_id', $orderIds)
                ->get()
                ->toArray();
            $shippingOrderIds = array_column($shippingInfos, 'order_id');

            $oRoute = new OwnerRoutes();
            foreach ($res['data'] as $key => $value) {

                // 价格转换为元
                $res['data'][$key]['price'] = $value['price'] / 100;

                $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($value['route_id'], $oRoute, [3], [3]);
                $res['data'][$key]['src'] = $routeInfo['srcDetail'];
                $res['data'][$key]['dst'] = $routeInfo['dstDetail'];
                $res['data'][$key]['car_need_num'] = intval($value['total_car_num']) - intval($value['shipping_car_num']);

                $carSites = CarSite::select(['site_value', 'site_type'])
                    ->where('site_status', 1)
                    ->whereIn('id', [
                        $value['model_site_id'],
                        $value['box_site_id'],
                        $value['length_site_id']
                    ])
                    ->get()
                    ->toArray();
                $siteInfo = sizeof($carSites) ? array_column($carSites, 'site_value', 'site_type') : [];
                $res['data'][$key]['car_model'] = $siteInfo[CarService::CAR_MODEL] ?? '';
                $res['data'][$key]['car_box'] = $siteInfo[CarService::CAR_BOX] ?? '';
                $res['data'][$key]['car_length'] = $siteInfo[CarService::CAR_LENGTH] ?? '';

                // 司机接单标记
                $res['data'][$key]['is_order_driver'] = in_array($value['id'], $shippingOrderIds) ? 1 : -1;

                // 时间转换
                $res['data'][$key]['start_time'] = date('Y-m-d', strtotime($value['start_time']));
                $res['data'][$key]['end_time'] = date('Y-m-d', strtotime($value['end_time']));

                unset(
                    $res['data'][$key]['id'],
                    $res['data'][$key]['model_site_id'],
                    $res['data'][$key]['box_site_id'],
                    $res['data'][$key]['length_site_id'],
                    $res['data'][$key]['route_id']
                );
            }

            return $this->table($res['data'], $res['total']);

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 货源详情 - 用于展示给司机
     * @see https://run.mockplus.cn/DQQd1cZtfuI7ebzw/index.html?to=D885544F-E847-4CE3-8F75-0F862AF31521
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getOrderDetailForDrivers(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'order_no' => 'required'
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $fields = [
                'v_orders.route_id',
                'v_orders.order_remark',
                'v_orders.cargo_type',
                'v_orders.price',
                'v_orders.price_unit',
                'v_orders.loss_limit', // 货损范围
                'v_orders.loss_price', // 超出部分扣款单价
                'v_orders.loss_price_unit', // 扣款单价单位 1:元/吨,2:元/件,3:元/个,4:元/趟
                'v_orders.total_car_num',
                'v_orders.shipping_car_num',
                'v_orders.start_time',
                'v_orders.end_time',
                'v_orders.car_scheme_id',
                'v_orders.created_at',
                'scheme.model_site_id',
                'scheme.box_site_id',
                'scheme.length_site_id'
            ];
            $oOrder = Order::select($fields)
                ->leftJoin('v_car_schemes AS scheme', 'scheme.id', '=', 'v_orders.car_scheme_id')
                ->where('v_orders.order_no', $request->get('order_no'))
                ->first();
            if (is_null($oOrder)) {
                return $this->success('没有数据');
            }

            $carSites = CarSite::select(['site_value', 'site_type'])
                ->where('site_status', 1)
                ->whereIn('id', [
                    $oOrder->model_site_id,
                    $oOrder->box_site_id,
                    $oOrder->length_site_id
                ])
                ->get()
                ->toArray();
            $siteInfo = sizeof($carSites) ? array_column($carSites, 'site_value', 'site_type') : [];

            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3]);

            $builder = [];
            $builder['time_ago'] = Time::swtichTimeStamp(strtotime($oOrder->created_at)); // 多少分钟/小时/天前
            $builder['msg_fee'] = config('pay.msg_amount'); // 信息费用
            $builder['order_remark'] = $oOrder->order_remark; // 订单备注
            $builder['route_info']['distance'] = $routeInfo['distance'] ?? 0;
            $builder['route_info']['src'] = $routeInfo['srcDetail'] ?? '';
            $builder['route_info']['dst'] = $routeInfo['dstDetail'] ?? '';
            $builder['cargo_info']['cargo_type'] = $oOrder->cargo_type;
            $builder['cargo_info']['price'] = $oOrder->price;
            $builder['cargo_info']['price_unit'] = $oOrder->price_unit;
            $builder['cargo_info']['loss_limit'] = $oOrder->loss_limit;
            $builder['cargo_info']['loss_price'] = $oOrder->loss_price;
            $builder['cargo_info']['loss_price_unit'] = $oOrder->loss_price_unit;
            $builder['cargo_info']['total_car_num'] = $oOrder->total_car_num;
            $builder['cargo_info']['shipping_car_num'] = $oOrder->shipping_car_num;
            $builder['cargo_info']['start_time'] = $oOrder->start_time;
            $builder['cargo_info']['end_time'] = $oOrder->end_time;
            $builder['car_requirements']['car_model'] = $siteInfo[CarService::CAR_MODEL] ?? '';
            $builder['car_requirements']['car_box'] = $siteInfo[CarService::CAR_BOX] ?? '';
            $builder['car_requirements']['car_length'] = $siteInfo[CarService::CAR_LENGTH] ?? '';

            return $this->success('数据获取成功', $builder);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
}